package com.youxin.foundation.utils.thread;

import java.util.concurrent.ExecutorService;
import java.util.concurrent.LinkedBlockingQueue;
import java.util.concurrent.ThreadPoolExecutor;
import java.util.concurrent.TimeUnit;
import com.youxin.foundation.utils.locks.LockObject;

/**
 * 全局多任务缓存池,使用场景1,B端数据修改.C端监听
 * 
 * @author yingde.cao
 *
 */
public class BaseThreadPool {
	
	public static final int CORE_POOL_SIZE = 100;
	public static final int MAX_POOL_SIZE = 1000;
	public static final long KEEP_ALIVE_TIME = 5000;

	protected LinkedBlockingQueue<Runnable> blockingQueue = new LinkedBlockingQueue<>();

	protected ExecutorService executorService;

	public BaseThreadPool() {
		this(CORE_POOL_SIZE, MAX_POOL_SIZE, KEEP_ALIVE_TIME);
	}

	public BaseThreadPool(int corePoolSize, int maxPoolSize) {
		this(corePoolSize, maxPoolSize, KEEP_ALIVE_TIME);
	}

	public BaseThreadPool(int corePoolSize, int maxPoolSize, long keepAliveTime) {
		executorService = new ThreadPoolExecutor(corePoolSize, maxPoolSize, keepAliveTime, TimeUnit.MILLISECONDS,
				blockingQueue, new BaseThreadFactory(ScheduleThreadPool.class.getName()));
	}

	public ExecutorService getExecutorService() {
		return executorService;
	}

	public void setExecutorService(ExecutorService executorService) {
		this.executorService = executorService;
	}

	private static BaseThreadPool threadPool;

	/**
	 * 单例
	 * 
	 * @param corePoolSize
	 *            线程池核心运行数
	 * @param maxPoolSize
	 *            最大线程池
	 * @param keepAliveTime
	 *            保留时间
	 * @return
	 */
	public static BaseThreadPool instance(int corePoolSize, int maxPoolSize, long keepAliveTime) {
		if (threadPool == null) {
			LockObject.lock(() -> {
				if (threadPool != null) {
					return;
				}
				threadPool = new BaseThreadPool(corePoolSize, maxPoolSize, keepAliveTime);
			});
		}
		return threadPool;
	}
	
	
	public  void shutdown()
	{
		try {
			if(executorService!=null)
			{
				executorService.shutdown();
			}
		} catch (Exception e) {
			// TODO: handle exception
		}		
	}
	
	public static boolean stop()
	{
		try {
			if(threadPool!=null)
			{
				threadPool.shutdown();
				return true;
			}
		} catch (Exception e) {
			return true;
		}	
		return false;
	}

	/**
	 * 添加运行任务
	 * 
	 * @param runnable
	 */
	public static void addTask(Runnable runnable) {
		if (threadPool == null) {
			instance(CORE_POOL_SIZE, MAX_POOL_SIZE, KEEP_ALIVE_TIME);
		}
		threadPool.getExecutorService().execute(runnable);
	}

}
